package com.twu.biblioteca;

import com.javafx.tools.doclets.internal.toolkit.util.DocFinder;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;

public class BibliotecaApp {

    private Scanner console;
    private PrintStream output;
    private Library libraryStore;

    public BibliotecaApp(PrintStream output) {
        this.output = output;
        this.libraryStore = new Library(this.output);
        console = new Scanner(System.in);

        runApp();
    }

    public BibliotecaApp(InputStream in, PrintStream output) {
        this.output = output;

        this.libraryStore = new Library(this.output);
        console = new Scanner(in);

        runApp();
    }

    private void runApp() {
        printWelcomeMessage();
        printOptions();

        handleUserInput(getUserInput());
    }

    private void printWelcomeMessage() {
        output.println("Welcome to the Bangalore Biblioteca!");
        output.println("====================================");
    }

    private void printOptions() {
        output.println("\r\nPlease select an option:");
        output.println("Enter L to list all books in Biblioteca");
        output.println("Enter F to list all available books in Biblioteca");
        output.println("Enter C to checkout a book");
        output.println("Enter R to check-in a book");
        output.println("Enter Q to quit Biblioteca");
    }

    public void handleUserInput(char input) {
        switch(input) {
            case 'C':
            case 'c':
                checkOutBook();
                break;
            case 'L':
            case 'l':
                libraryStore.printBooksList(libraryStore.getAllBooks());
                break;
            case 'F':
            case 'f':
                libraryStore.printCompleteBookInformation(libraryStore.getAvailableBooks());
                break;
            case 'R':
            case 'r':
                checkInBook();
                break;
            case 'Q':
            case 'q':
                return;
            default:
                output.println("The option you chose was invalid, try again:");
                break;
        }
        handleUserInput(getUserInput());
    }

    protected char getUserInput() {
        String input = console.nextLine();
        try {
            return input.charAt(0);
        } catch(StringIndexOutOfBoundsException err) {
            return getUserInput();
        }
    }

    protected void checkOutBook() {
        Book toRent = null;
        try {
            output.println("Enter the ID of a book to check it out...");
            int index = console.nextInt();

            toRent = libraryStore.getAvailableBooks().get(index);
            libraryStore.checkOut(toRent);

            output.println("Congratulations! You have checked out " + toRent.getTitle());

        } catch (InputMismatchException numberErr) {
            output.println("Your input was not recognised as a number");
            return;
        } catch (IndexOutOfBoundsException indexErr) {
            output.println("We don't have a book with that index, try again");
            checkOutBook();
        } catch (NullPointerException nullErr) {
            output.println(nullErr.getMessage());
            return;
        }
    }

    protected void checkInBook() {
        Book toReturn = null;
        try {
            output.println("Books which are currently being returned are: ");
            libraryStore.printCompleteBookInformation(libraryStore.getUnavailableBooks());

            output.println("Enter the ID of a book to return it...");
            int index = console.nextInt();

            toReturn = libraryStore.getUnavailableBooks().get(index);
            libraryStore.checkIn(toReturn);

            output.println("Thank you for returning " + toReturn.getTitle());

        } catch (InputMismatchException numberErr) {
            output.println("Your input was not recognised as a number");
            return;
        } catch (IndexOutOfBoundsException indexErr) {
            output.println("That book doesn't seem to be on loan at the moment");
            return;
        } catch (NullPointerException nullErr) {
            output.println(nullErr.getMessage());
            return;
        }

        output.print("Please select another menu option: ");
    }
}
